home *** CD-ROM | disk | FTP | other *** search
/ Aminet 33 / Aminet 33 - October 1999.iso / Aminet / util / misc / VMM_src.lha / VMM / VM_Manager.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-12-16  |  15.7 KB  |  656 lines

  1. #include <exec/types.h>
  2. #include "defs.h"
  3. #include "Manager_Priv.h"
  4.  
  5. static char rcsid [] = "$Id: VM_Manager.c,v 3.6 95/12/16 18:36:53 Martin_Apel Exp $";
  6.  
  7. /*********************************************************************/
  8.  
  9. PRIVATE BOOL LockPage (ULONG Page)
  10.  
  11. {
  12. struct VMMsg *LockMsg;
  13.  
  14. if ((LockMsg = DoOrigAllocMem (sizeof (struct VMMsg), MEMF_PUBLIC)) == NULL)
  15.   return (FALSE);
  16.  
  17. LockMsg->VMCommand = VMCMD_LockPage;
  18. LockMsg->PageAddress  = Page;
  19. LockMsg->ReplySignal = 0;
  20. PutMsg (PageHandlerPort, (struct Message*)LockMsg);
  21.  
  22. Wait (1L << LockAckSignal);
  23. return (ThisPageLocked);
  24. }
  25.   
  26. /*********************************************************************/
  27.  
  28. PRIVATE BOOL LockPages (ULONG From, ULONG To)
  29.  
  30. {
  31. ULONG Page;
  32.  
  33. for (Page = PAGEADDR (From); Page <= PAGEADDR (To-1); Page += PAGESIZE)
  34.   {
  35.   if (!LockPage (Page))
  36.     return (FALSE);
  37.   }
  38.  
  39. return (TRUE);
  40. }
  41.  
  42. /*********************************************************************/
  43.  
  44. PRIVATE BOOL LoadRemainingPages (void)
  45.  
  46. {
  47. /* Walk the memory list to find out how many page frames are still needed.
  48.  */
  49.  
  50. struct MemChunk *mc;
  51. ULONG start_of_alloc,
  52.       end_of_alloc,
  53.       end_of_last_alloc;
  54.  
  55. start_of_alloc = (ULONG)(VirtMem + 1);  /* points behind MemHeader */
  56. end_of_alloc = (ULONG)VirtMem;
  57.  
  58. OBTAIN_VM_SEMA;
  59. for (mc = VirtMem->mh_First; mc != NULL; mc = mc->mc_Next)
  60.   {
  61.   end_of_last_alloc = end_of_alloc;
  62.   end_of_alloc = (ULONG)mc;
  63.   if (start_of_alloc < end_of_alloc)
  64.     {
  65.     if (!LockPages (start_of_alloc, end_of_alloc))
  66.       {
  67.       RELEASE_VM_SEMA;
  68.       return (FALSE);
  69.       }
  70.     }
  71.     
  72.   start_of_alloc = (ULONG)mc + mc->mc_Bytes;
  73.   }
  74.  
  75. if (start_of_alloc < (ULONG)VirtMem->mh_Upper)
  76.   {
  77.   if (!LockPages (start_of_alloc, (ULONG)VirtMem->mh_Upper))
  78.     {
  79.     RELEASE_VM_SEMA;
  80.     return (FALSE);
  81.     }
  82.   }
  83.  
  84. RELEASE_VM_SEMA;
  85. return (TRUE);
  86. }
  87.  
  88. /*********************************************************************/
  89.  
  90. PRIVATE BOOL ExitPossible (void)
  91.  
  92. {
  93. /* This routine checks if it is currently possible to exit VMM.
  94.  * 1. It tries to remove library if it is installed.
  95.  * 2. It checks the remaining allocated virtual memory. If the still 
  96.  *    allocated memory fits into the page frames, quit is allowed.
  97.  *    CAUTION: This may cause the VM_Manager to block for a page-fault.
  98.  */
  99.  
  100. struct Library *VMLib;
  101. struct MemHeader *mh;
  102. ULONG size = 0;
  103.  
  104. Forbid ();
  105. VMLib = (struct Library*)FindName (&(SysBase->LibList), LIBNAME);
  106. if (VMLib != NULL)
  107.   {
  108.   /* Try to remove library. */
  109.   RemLibrary (VMLib);
  110.   if (FindName (&(SysBase->LibList), LIBNAME) != NULL)
  111.     {
  112.     /* Library couldn't be expunged */
  113.     Permit ();
  114.     PRINT_DEB ("Library is still running", 0L);
  115.     ReportError (GetVMMString (msgVMMLibStillOpen), ERR_CONTINUE);
  116.     return (FALSE);
  117.     }
  118.   }
  119. Permit ();
  120.  
  121. /* It's a bit troublesome to find out, if there are enough page frames
  122.  * to hold the rest of the allocated memory. To avoid this, simple
  123.  * tests are done first.
  124.  */
  125.  
  126. if (VirtMem->mh_Free == AddedMemSize - sizeof (struct MemHeader))
  127.   return (TRUE);
  128.  
  129. size = 0;
  130. Forbid ();
  131. for (mh = (struct MemHeader*)SysBase->MemList.lh_Head;
  132.      mh->mh_Node.ln_Succ != NULL; mh = (struct MemHeader*)mh->mh_Node.ln_Succ)
  133.   {
  134.   if ((mh->mh_Attributes & CurrentConfig.MemFlags) == CurrentConfig.MemFlags)
  135.     size += (ULONG)mh->mh_Upper - (ULONG)mh->mh_Lower;
  136.   }
  137. Permit ();
  138.  
  139. PRINT_DEB ("Maximum size of available memory: %ld", size);
  140. PRINT_DEB ("%ld bytes of VM are allocated", AddedMemSize - VirtMem->mh_Free);
  141. if (AddedMemSize - VirtMem->mh_Free > size)
  142.   {
  143.   ReportError (GetVMMString(msgNotEnoughFrames), ERR_CONTINUE);
  144.   return (FALSE);
  145.   }
  146.  
  147. if (!LoadRemainingPages ())
  148.   {
  149.   struct VMMsg UnlockMsg;
  150.  
  151.   PRINT_DEB ("Not enough frames to exit", 0L);
  152.   UnlockMsg.VMCommand = VMCMD_UnlockAllPages;
  153.   UnlockMsg.VMSender = (struct Task*)VM_ManagerProcess;
  154.   UnlockMsg.ReplySignal = LockAckSignal;
  155.   PutMsg (PageHandlerPort, (struct Message*) &UnlockMsg);
  156.   Wait (1L << LockAckSignal);
  157.  
  158.   ReportError (GetVMMString(msgNotEnoughFrames), ERR_CONTINUE);
  159.   return (FALSE);
  160.   }
  161.  
  162. EarlyExit = TRUE;
  163. ReportError (GetVMMString (msgStillVMAllocated), ERR_NOERROR);
  164. return (TRUE);   
  165. }
  166.  
  167. /*********************************************************************/
  168.  
  169. BOOL TryToQuit (void)
  170.  
  171. {
  172. PRINT_DEB ("Trying to quit", 0L);
  173. Delay (50L);            /* Leave a little time for the program requesting
  174.                          * to quit to free its memory
  175.                          */
  176. DISABLE_VM;
  177. if (ExitPossible ())
  178.     {
  179.     PRINT_DEB ("Quit possible", 0L);
  180.     NoMoreVM ();
  181.  
  182.     if (VMPort->mp_Node.ln_Name != NULL)
  183.       {
  184.       RemPort (VMPort);
  185.       VMPort->mp_Node.ln_Name = NULL;
  186.       }
  187.  
  188.     if (RexxPort->mp_Node.ln_Name != NULL)
  189.       {
  190.       RemPort (RexxPort);
  191.       RexxPort->mp_Node.ln_Name = NULL;
  192.       }
  193.  
  194.     return (TRUE);
  195.     }
  196.  
  197. ENABLE_VM;
  198. return (FALSE);
  199. }
  200.  
  201. /*********************************************************************/
  202.  
  203. void FillStat (struct VMMsg *StatMsg)
  204.  
  205. {
  206. struct TrapStruct *tmp;
  207. int i;
  208.  
  209. StatMsg->st_VMSize = AddedMemSize - sizeof (struct MemHeader);
  210. StatMsg->st_VMFree = VirtMem->mh_Free;
  211. StatMsg->st_Faults = NumPageFaults;
  212. StatMsg->st_PagesWritten = PagesWritten;
  213. StatMsg->st_PagesRead = PagesRead;
  214. StatMsg->st_Frames = NumPageFrames;
  215. StatMsg->st_PagesUsed = SlotsUsed ();
  216. StatMsg->st_PageSize = PAGESIZE;
  217.  
  218. i = 0;
  219. Forbid ();
  220. for (tmp = (struct TrapStruct*)Free.lh_Head;
  221.      tmp->TS_Node.mln_Succ != NULL;
  222.      tmp = (struct TrapStruct*)tmp->TS_Node.mln_Succ)
  223.   i++;
  224. Permit ();
  225. StatMsg->st_TrapStructsFree = i;
  226. }
  227.  
  228. /*********************************************************************/
  229.  
  230. PRIVATE void FillMemHeader (struct VMMsg *ReqMsg)
  231.  
  232. {
  233. ReqMsg->VMCommand = VMCMD_InitReady;
  234. ReqMsg->VMHeader  = VirtMem;
  235. ReqMsg->VMSema    = &VirtMemSema;
  236. ReqMsg->MLName    = MEMLISTNAME;
  237. }
  238.  
  239. /*********************************************************************/
  240.  
  241. int ShowGUI (void)
  242.  
  243. {
  244. BPTR InOutHandle;
  245. char command_buffer [200];
  246.  
  247. if (ExtCxPort->PrefsTask != NULL)
  248.   {
  249.   PRINT_DEB ("Prefs already running", 0L);
  250.   Signal (ExtCxPort->PrefsTask, 1L << ExtCxPort->ShowSignal);
  251.   return (SUCCESS);
  252.   }
  253.  
  254. DISABLE_VM;
  255.  
  256. if ((InOutHandle = Open ("CON:0/0/640/200/VMM Window/CLOSE/AUTO/WAIT", 
  257.                          MODE_NEWFILE)) == NULL)
  258.   {
  259.   PRINT_DEB ("Couldn't open shell window", 0L);
  260.   ENABLE_VM;
  261.   return (ERR_NOT_ENOUGH_MEM);
  262.   }
  263.  
  264. PRINT_DEB ("Trying to create process", 0L);
  265.  
  266. sprintf (command_buffer, "\"%s\"", CxParams->PrefsPath);
  267. if (SystemTags (command_buffer,
  268.                 SYS_Input, (ULONG)InOutHandle,
  269.                 SYS_Output, NULL,
  270.                 SYS_Asynch, (ULONG) TRUE,
  271.                 NP_Priority, 0L,
  272.                 TAG_DONE, 0L) != NULL)
  273.   {
  274.   PRINT_DEB ("Couldn't create preferences process", 0L);
  275.   ENABLE_VM;
  276.   return (ERR_NO_PREFS);
  277.   }
  278.  
  279. PRINT_DEB ("Successfully created preferences process", 0L);
  280. ENABLE_VM;
  281. return (SUCCESS);
  282. }
  283.  
  284. /*********************************************************************/
  285.  
  286. void HideGUI (void)
  287.  
  288. {
  289. Forbid ();
  290. if (ExtCxPort->PrefsTask != NULL)
  291.   Signal (ExtCxPort->PrefsTask, SIGBREAKF_CTRL_C);
  292. Permit ();
  293. }
  294.  
  295. /*********************************************************************/
  296.  
  297. PRIVATE BOOL HandleVMMsg (void)
  298.  
  299. {
  300. struct VMMsg *VMMsg;
  301. BOOL Quit = FALSE;
  302. BOOL NoReply;
  303.  
  304. UWORD Command;
  305.  
  306. while ((VMMsg = (struct VMMsg*)GetMsg (VMPort)))
  307.   {
  308.   PRINT_DEB ("Received VMMsg", 0L);
  309.   Command = VMMsg->VMCommand;
  310.   NoReply = FALSE;
  311.   switch (Command)
  312.     {
  313.     /**********************/
  314.     case VMCMD_AskAllocMem:
  315.       ExtCheckVirtMem (VMMsg->VMSender);
  316.       break;
  317.  
  318.     /**********************/
  319.     case VMCMD_QuitAll:
  320.       if (TryToQuit ())
  321.         Quit = TRUE;
  322.       break;
  323.  
  324.     /**********************/
  325.     case VMCMD_AskStat:
  326.       PRINT_DEB ("Received AskStat msg", 0L);
  327.       FillStat (VMMsg);
  328.       break;
  329.  
  330.     /**********************/
  331.     case VMCMD_ReqMemHeader:
  332.       PRINT_DEB ("Received ReqMemHeader msg", 0L);
  333.       FillMemHeader (VMMsg);
  334.       break;
  335.  
  336.     /**********************/
  337.     case VMCMD_DisableVM:
  338.       PRINT_DEB ("Received disable msg from Prefs program", 0L);
  339.       DISABLE_VM;
  340.       break;
  341.  
  342.     /**********************/
  343.     case VMCMD_EnableVM:
  344.       PRINT_DEB ("Received enable msg from Prefs program", 0L);
  345.       ENABLE_VM;
  346.       break;
  347.  
  348.     /**********************/
  349.     case VMCMD_AskVMUsage:
  350.       PRINT_DEB ("Received AskVMUsage message", 0L);
  351.       /* A separate task will reply this message when finished */
  352.       VMUsageInfo (VMMsg);
  353.       NoReply = TRUE;
  354.       break;
  355.  
  356.     /**********************/
  357.     case VMCMD_AskConfig:
  358.       PRINT_DEB ("Received AskConfig message", 0L);
  359.       *(VMMsg->Config) = CurrentConfig;
  360.       break;
  361.  
  362.     /**********************/
  363.     default:
  364.       PRINT_DEB ("Internal error: Unknown msg type. Type is %ld", 
  365.                  (ULONG)Command);
  366.       PRINT_DEB ("Sender is", 0L);
  367.       PRINT_DEB (VMMsg->VMSender->tc_Node.ln_Name, 0L);
  368. #ifdef DEBUG
  369.       ColdReboot ();
  370. #endif
  371.     }
  372.  
  373.   if (!NoReply)
  374.     {
  375.     if (VMMsg->ReplySignal == NULL)
  376.       {
  377.       PRINT_DEB ("Freeing VMMsg", 0L);
  378.       FreeMem (VMMsg, sizeof (struct VMMsg));
  379.       }
  380.     else
  381.       {
  382.       Signal (VMMsg->VMSender, 1L << VMMsg->ReplySignal);
  383.       PRINT_DEB ("Returning VMMsg to sender", 0L);
  384.       }
  385.     }
  386.   }
  387. return (Quit);
  388. }
  389.  
  390. /*********************************************************************/
  391.  
  392. PRIVATE BOOL HandleCxMsg (void)
  393.  
  394. {
  395. CxMsg *MyMsg;
  396. BOOL Quit = FALSE;
  397. int rc;
  398.  
  399. while ((MyMsg = (CxMsg*)GetMsg (&(ExtCxPort->CxPort))) != NULL)
  400.   {
  401.   switch (CxMsgType (MyMsg))
  402.     {
  403.     case CXM_IEVENT: 
  404.       switch (CxMsgID (MyMsg))
  405.         {
  406.         case APPEAR_ID: if ((rc = ShowGUI ()) != SUCCESS)
  407.                           RunTimeError (rc);
  408.                         break;
  409.  
  410.         case ENABLE_ID: if (!VMEnabled)
  411.                           {
  412.                           VMEnabled = TRUE;
  413.                           ENABLE_VM;
  414.                           DisplayBeep (NULL);
  415.                           }
  416.                         break;
  417.  
  418.         case DISABLE_ID:if (VMEnabled)
  419.                           {
  420.                           VMEnabled = FALSE;
  421.                           DISABLE_VM;
  422.                           DisplayBeep (NULL);
  423.                           }
  424.                         break;
  425.         }
  426.       break;
  427.  
  428.     case CXM_COMMAND:
  429.       switch (CxMsgID (MyMsg))
  430.         {
  431.         case CXCMD_DISABLE: 
  432.                PRINT_DEB ("Received CXCMD_DISABLE", 0L);
  433.                if (VMEnabled)
  434.                  {
  435.                  VMEnabled = FALSE;
  436.                  DISABLE_VM;
  437.                  }
  438.                PRINT_DEB ("Deactivating broker", 0L);
  439.                ActivateCxObj (CxParams->Broker, FALSE);
  440.                PRINT_DEB ("Returned from deactivate", 0L);
  441.                break;
  442.  
  443.         case CXCMD_ENABLE: 
  444.                PRINT_DEB ("Received CXCMD_ENABLE", 0L);
  445.                ActivateCxObj (CxParams->Broker, TRUE);
  446.                if (!VMEnabled)
  447.                  {
  448.                  VMEnabled = TRUE;
  449.                  ENABLE_VM;
  450.                  }
  451.                break;
  452.  
  453.         case CXCMD_APPEAR: 
  454.                PRINT_DEB ("Received CXCMD_APPEAR", 0L);
  455.                if ((rc = ShowGUI ()) != SUCCESS)
  456.                  RunTimeError (rc);
  457.                break;
  458.  
  459.         case CXCMD_DISAPPEAR: 
  460.                PRINT_DEB ("Received CXCMD_DISAPPEAR", 0L);
  461.                HideGUI ();
  462.                break;
  463.  
  464.         case CXCMD_KILL: 
  465.                PRINT_DEB ("Received CXCMD_KILL", 0L);
  466.                if (TryToQuit ())
  467.                  {
  468.                  HideGUI ();
  469.                  Quit = TRUE;
  470.                  }
  471.                break;
  472.         }
  473.       break;
  474.     }
  475.  
  476.   ReplyMsg ((struct Message*) MyMsg);
  477.   }
  478.  
  479. return (Quit);
  480. }
  481.  
  482. /*********************************************************************/
  483.  
  484. PRIVATE void NewConfigReceived (void)
  485.  
  486. {
  487. struct VMMsg *CfgMsg;
  488. int rc;
  489. ULONG OldWBufSize = CurrentConfig.WriteBuffer;
  490.  
  491. NoMoreVM ();
  492. if ((rc = ReadConfigFile (CFG_FILENAME)) != SUCCESS)
  493.   {
  494.   RunTimeError (rc);
  495.   return;
  496.   }
  497.  
  498. /* try to accommodate to the new values. The values which have to 
  499.  * be taken into account are:
  500.  *   MinMem
  501.  *   MaxMem
  502.  *   PrintStat
  503.  *   VMPriority
  504.  *   WriteBuffer
  505.  *   Enable and DisableVM hotkeys
  506.  */
  507.  
  508. /* New VMPriority value */
  509. Forbid ();
  510. if (VirtMem->mh_Node.ln_Name != NULL)      
  511.   {
  512.   Remove ((struct Node*)VirtMem);
  513.   VirtMem->mh_Node.ln_Pri = CurrentConfig.VMPriority;
  514.   Enqueue (&(SysBase->MemList), (struct Node*)VirtMem);
  515.   }
  516. Permit ();
  517.  
  518. /* New PrintStat value */
  519. if (CurrentConfig.StatEnabled && (FindTask (STAT_NAME) == NULL))
  520.   {
  521.   if ((rc = LaunchStat ()) != SUCCESS)
  522.     RunTimeError (rc);
  523.   }
  524. else if (!CurrentConfig.StatEnabled && (FindTask (STAT_NAME) != NULL))
  525.   Signal (StatTask, 1L << StatQuitSignal);
  526.  
  527. /* New MinMem, MaxMem values */
  528. if ((CfgMsg = DoOrigAllocMem (sizeof (struct VMMsg), MEMF_PUBLIC)) == NULL)
  529.   {
  530.   PRINT_DEB ("No mem for Config message to pagehandler", 0L);
  531.   return;
  532.   }
  533.  
  534. CfgMsg->VMSender = FindTask (NULL);
  535. CfgMsg->ReplySignal = NULL;
  536. CfgMsg->VMCommand = VMCMD_NewConfig;
  537. PutMsg (PageHandlerPort, (struct Message*)CfgMsg);
  538.  
  539. /* New DontCacheZ2RAM value */
  540. AllowZorroIICaching (CurrentConfig.CacheZ2RAM);
  541. if ((rc = SwitchFastROM (CurrentConfig.FastROM)) != SUCCESS)
  542.   {
  543.   RunTimeError (rc);
  544.   CurrentConfig.FastROM = FALSE;
  545.   }
  546.  
  547. /* New PatchWB value */
  548. if (CurrentConfig.PatchWB && (OrigSetWindowTitles == NULL))
  549.   {
  550.   PRINT_DEB ("Patching SetWindowTitles ()", 0L);
  551.   OrigSetWindowTitles = (void (*) ()) SetFunction ((struct Library*)IntuitionBase,
  552.                                      -0x114, (ULONG (*) ()) SetWindowTitlesPatch);
  553.   }
  554. else if (!CurrentConfig.PatchWB && (OrigSetWindowTitles != NULL))
  555.   {
  556.   SetFunction ((struct Library*)IntuitionBase, -0x114, 
  557.                (ULONG (*) ()) OrigSetWindowTitles);
  558.   OrigSetWindowTitles = NULL;
  559.   }
  560.  
  561. /* New value for write-buffer */
  562. if (OldWBufSize != CurrentConfig.WriteBuffer)
  563.   {
  564.   PRINT_DEB ("WriteBuffer size has changed", 0L);
  565.   DesiredWriteBufferSize = CurrentConfig.WriteBuffer;
  566.   CreateTask (WBUF_ALLOC_NAME, 5L, AllocNewCache, 1000L);
  567.   }
  568.  
  569. SetFilter (CxParams->EnableFilter, CurrentConfig.EnableHotkey);
  570. SetFilter (CxParams->DisableFilter, CurrentConfig.DisableHotkey);
  571. }
  572.  
  573. /*********************************************************************/
  574.  
  575. void VM_Manager (void)
  576.  
  577. {
  578. ULONG ReceivedSignals;
  579. ULONG WaitMask;
  580. BOOL DoQuit = FALSE;
  581. struct MsgPort *StarterPort;
  582. struct VMMsg *InitMsg;
  583. int rc;
  584.  
  585. rc = Init_VM_Manager ();
  586.  
  587. if (((StarterPort = FindPort (STARTER_PORT_STD)) == NULL) &&
  588.     ((StarterPort = FindPort (STARTER_PORT_LIB)) == NULL))
  589.   {
  590.   PRINT_DEB ("VERY, VERY STRANGE: COULDN'T FIND STARTER PORT", 0L);
  591.   return;
  592.   }
  593. else if ((InitMsg = DoOrigAllocMem (sizeof (struct VMMsg), MEMF_PUBLIC)) == NULL)
  594.   {
  595.   PRINT_DEB ("Not enough memory for init msg", 0L);
  596.   Signal (StarterPort->mp_SigTask, 1L << StarterPort->mp_SigBit);
  597.   InitError (ERR_NOT_ENOUGH_MEM);
  598.   Cleanup_VM_Manager ();
  599.   return;
  600.   }
  601.  
  602. InitMsg->VMSender  = (struct Task*)VM_ManagerProcess;
  603. InitMsg->ReplySignal = NULL;
  604.  
  605. if (rc != SUCCESS)
  606.   {
  607.   InitError (rc);
  608.   InitMsg->VMCommand = VMCMD_InitFailed;
  609.   PutMsg (StarterPort, (struct Message*)InitMsg);
  610.   Cleanup_VM_Manager ();
  611.   return;
  612.   }
  613.  
  614. InitMsg->VMCommand = VMCMD_InitReady;
  615. InitMsg->VMHeader  = VirtMem;
  616. InitMsg->VMSema    = &VirtMemSema;
  617. PutMsg (StarterPort, (struct Message*)InitMsg);
  618.  
  619. WaitMask = (1L << VMPort->mp_SigBit) | (1L << CfgChangeSignal) |
  620.            (1L << RexxPort->mp_SigBit);
  621.  
  622. if (ExtCxPort != NULL)
  623.   {
  624.   PRINT_DEB ("Including CXSigBit in WaitMask", 0L);
  625.   WaitMask |= (1L << ExtCxPort->CxPort.mp_SigBit);
  626.   }
  627.  
  628. while (!DoQuit)
  629.   {
  630.   PRINT_DEB ("Waiting for signals", 0L);
  631.   ReceivedSignals = Wait (WaitMask);
  632.   PRINT_DEB ("Received signals", 0L);
  633.  
  634.   if (ReceivedSignals & (1L << CfgChangeSignal))
  635.     {
  636.     PRINT_DEB ("Configuration changed", 0L);
  637.     NewConfigReceived ();
  638.     }
  639.  
  640.   if ((ExtCxPort != NULL) && 
  641.       (ReceivedSignals & (1L << ExtCxPort->CxPort.mp_SigBit)))
  642.     {
  643.     PRINT_DEB ("Received commodities message", 0L);
  644.     DoQuit = HandleCxMsg () || DoQuit;
  645.     }
  646.  
  647.   if (ReceivedSignals & (1L << RexxPort->mp_SigBit))
  648.     DoQuit = HandleRexxMsg () || DoQuit;
  649.  
  650.   if (ReceivedSignals & (1L << VMPort->mp_SigBit))
  651.     DoQuit = HandleVMMsg () || DoQuit;
  652.   }
  653.  
  654. Cleanup_VM_Manager ();
  655. }
  656.